export function localStorage(key, value) {
  if (value !== undefined) {
    return window.localStorage.setItem(key, value)
  } else {
    return window.localStorage.getItem(key)
  }
}
export function sessionStorage(key, value) {
  if (value !== undefined) {
    return window.sessionStorage.setItem(key, JSON.stringify(value))
  } else {
    return JSON.parse(window.sessionStorage.getItem(key))
  }
}
/**
 * 校验手机号
 * @param {String} v - 要校验的值
 * @return {Boolean} true或false
 */
export function phone(v) {
  return /^1(3|5|6|7|8|9)\d{9}$/.test(v)
}
/**
 * 校验密码
 * @param {String} v - 要校验的值
 * @return {Boolean} true或false
 */
export function password(v) {
  return /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,18}$/.test(v)
}
/**
 * 递增指定日期（不会改动原实例）
 * @param {Date} date - Date对象
 * @param {String} v - 格式串，支持运算符+/-，支持单位y/m/d/h/i/s(年/月/日/时/分/秒)
 * @param {String} [formatStr] - 返回的日期格式，如果指定则返回String类型
 * @return {Date|String} 运算后的Date对象或格式化结果（如果指定formatStr）
 * @example add(new Date('2012-02-29 16:04:00'), '1y'); //"2013-02-28 16:04:00"
 * @example add(new Date('2017-10-18 16:04:00'), '-2m'); //"2017-08-18 16:04:00"
 */
export function add (date, v, formatStr) {
  v = v.trim()
  const num = parseFloat(v) // 数值
  const unit = v.substr(-1) // 单位
  let time = date.getTime()
  let ret
  if (unit === 'y' || unit === 'm') { // 年 || 月
    ret = new Date(time)
    const d = date.getDate()
    ret.setDate(1) // 先把日置为1，避免计算错误
    unit === 'y' ? ret.setFullYear(ret.getFullYear() + num) : ret.setMonth(ret.getMonth() + num)
    ret.setDate(Math.min(d, getDayNum(ret))) // 回填日，保证不超过当月最后一天
  } else {
    switch (unit) {
      case 'd': // 日
        time += num * 86400000
        break
      case 'h': // 时
        time += num * 3600000
        break
      case 'i': // 分
        time += num * 60000
        break
      case 's': // 秒
        time += num * 1000
        break
    }
    ret = new Date(time)
  }
  return formatStr ? formatDate(ret, formatStr) : ret
}

/**
 * 格式化日期
 * @param {Date} date - Date对象
 * @param {String} [formatStr='Y-m-d'] - 需要输出的格式
 * @return {String} 格式化后的字符串
 * @example format(new Date()); //"2017-10-18 15:38:34"
 *          format(new Date(), 'Y年m月d日 星期N'); //"2017年10月18日 星期三"
 */
export function formatDate (date, formatStr = 'Y-m-d H:i:s') {
  let str = ''
  for (const c of formatStr) {
    switch (c) {
      case 'Y': // 年，4位
        str += String(date.getFullYear()).padStart(4, '0')
        break
      case 'm': // 月，2位
        str += String(date.getMonth() + 1).padStart(2, '0')
        break
      case 'n': // 月，没有前导0
        str += date.getMonth() + 1
        break
      case 'd': // 日，2位
        str += String(date.getDate()).padStart(2, '0')
        break
      case 'j': // 日，没有前导0
        str += date.getDate()
        break
      case 'H': // 小时，4位
        str += String(date.getHours()).padStart(2, '0')
        break
      case 'i': // 分，2位
        str += String(date.getMinutes()).padStart(2, '0')
        break
      case 's': // 秒，2位
        str += String(date.getSeconds()).padStart(2, '0')
        break
      case 'N': // 星期中的第几天，汉字，日、一、二等，1位
        str += getUTCDayCN(date)
        break
      default:
        str += c
    }
  }
  return str
}
/**
 * 获取该月的天数
 * @param {Date} date - Date对象
 * @return {Number} 该月的天数
 */
export function getDayNum (date) {
  const m = date.getMonth() + 1
  if (m === 2) { // 2月
    return isLeapYear(date) ? 29 : 28
  } else if (m === 4 || m === 6 || m === 9 || m === 11) {
    return 30
  } else {
    return 31
  }
}
/**
 * 是否闰年
 * @param {Date} date - Date对象
 * @return {Boolean} 是true 否false
 */
export function isLeapYear (date) {
  const year = date.getFullYear()
  return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0)
}
/**
 * 获取星期中的第几天
 * @param {Date} date - Date对象
 * @returns (String)日、一、二、...六
 */
export function getUTCDayCN (date) {
  switch (date.getUTCDay()) { // 0(周日)到6(周六)
    case 0:
      return '日'
    case 1:
      return '一'
    case 2:
      return '二'
    case 3:
      return '三'
    case 4:
      return '四'
    case 5:
      return '五'
    case 6:
      return '六'
  }
}